package com.minidb.sql_compliler;
import com.minidb.sql_compliler.Lexer.Token;
import com.minidb.sql_compliler.Lexer.TokenType;

import java.util.ArrayList;
import java.util.List;

//元数据管理
public class Parser {
    //语法分析器
    //将词法单元序列转换为抽象语法树(AST)
    private List<Token> tokens;
    private int pos = 0;

    // 获取当前词法单元
    public ASTNode parse(List<Token> tokens) {
        this.tokens = tokens;
        this.pos = 0;

        Token t =peek();
        // 根据第一个词法单元决定解析哪种SQL语句
        if (t.type ==TokenType.KEYWORD && t.value.equals("CREATE")) {
            return parseCreateTable();
        } else if (t.type ==TokenType.KEYWORD && t.value.equals("INSERT")) {
            return parseInsert();
        } else {
            throw new RuntimeException("Unsupported SQL statement " +t.value);
        }
    }

    // 查看当前词法单元但不移动位置
    private ASTNode.CreateTableNode parseCreateTable(){
        // 解析 CREATE TABLE 语句
        expect("CREATE");
        expect("TABLE");
        String tableName = expectIdentifier();

        //
        expect("(");
        List<ASTNode.ColumnDef> columns = new ArrayList<>();
        while (true) {
            String colName = expectIdentifier();
            String colType = expectIdentifier(); //简化 int, string
            columns.add(new ASTNode.ColumnDef(colName, colType));
            if (peek().value.equals(")")) {
                break;
            }
            expect(",");
        }
        expect(")");

        return new ASTNode.CreateTableNode(tableName, columns);
    }

    // 预期当前词法单元是特定值，否则抛出异常
    private ASTNode.InsertNode parseInsert() {
        // 解析 INSERT 语句
        expect("INSERT");
        expect("INTO");
        String tableName = expectIdentifier();

        expect("VALUES");
        expect("(");
        List<String> values = new ArrayList<>();
        while (true) {
            Token value = next();
            if (value.type == TokenType.NUMBER || value.type == TokenType.STRING) {
                values.add(value.value);
            } else {
                throw new RuntimeException("Expected value but found: " + value);
            }
            if (peek().value.equals(")")) {
                break;
            }
            expect(",");
        }
        expect(")");

        return new ASTNode.InsertNode(tableName, values);
    }

    // -- 辅助方法--
    // 预期当前词法单元是特定值，否则抛出异常
    private Token peek() {
        return tokens.get(pos);
    }
    // 预期当前词法单元是标识符，否则抛出异常
    private Token next() {
        return tokens.get(pos++);
    }

    private void expect(String expected) {
        Token t = next();
        if (!t.value.equalsIgnoreCase(expected) && !t.value.equals(expected)) {
            throw new RuntimeException("Expected " + expected + " but found: " + t);
        }
    }

    private String expectIdentifier(){
        Token t = next();
        if (t.type != TokenType.IDENTIFIER && t.type != TokenType.KEYWORD) {
            throw new RuntimeException("Expected identifier but found: " + t);
        }
        return t.value;
    }
}
